home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / snip9_91.arc / STRUCFIL.C < prev    next >
C/C++ Source or Header  |  1991-09-17  |  5KB  |  184 lines

  1. /*******************************************************************
  2.  * Generic structure <> disk file manipulations. These functions
  3.  * form a basic template for reading and writing structures to a 
  4.  * sequential file. This template is probably most useful for files
  5.  * with 500 or less records and eliminates the need for a more 
  6.  * elaborate file handler such as C-Tree, DB-Vista, Mix etc.
  7.  * Routines to put data in the struct is out of scope here.
  8.  * Written by Lynn Nash 8/28/91 and donated to the public domain.
  9.  */
  10. #include <io.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14.  
  15. #ifndef ERROR
  16. #define ERROR -1
  17. #define OK     0
  18. #endif
  19.  
  20. #ifndef TRUE
  21. #define TRUE 1
  22. #define FALSE !TRUE
  23. #endif
  24.  
  25. /* make sure the record structure is byte aligned */
  26. #pragma pack(1) 
  27.  
  28. static struct blackbook {
  29.     int delete_flag;        /* 0 = active  -1 = deleted */
  30.     int recordnum;          /* a sequential number in the file */
  31.    /* The data fields in asciiz.  */
  32.     char firstname[11];         
  33.     char lastname[16];         
  34.     char addr[26];          
  35.     char city[16];
  36.     char state[3];
  37.     char zip[10];
  38.     char phone[11];
  39. } rec, oldrec;             /* 97 byte record  * 2 */
  40.  
  41. #pragma pack()
  42.  
  43. /*-------------------- general globals ---------------------*/
  44.  
  45. static long cur_rec = 0;      /* the current record number */
  46. static FILE *fsptr = NULL;    /* fixed record data file pointer */
  47.  
  48. /* if file exists open in read/write mode else create file */
  49.  
  50. FILE * open_file(char *filename)
  51. {
  52.       if (access(filename, 0) == 0)
  53.             fsptr = fopen(filename, "rb+"); 
  54.       else  fsptr = fopen(filename, "wb+"); 
  55.       return fsptr;                       /* return the file pointer */
  56.  
  57. /* add new records to the data file */
  58.  
  59. int datadd(void)
  60. {
  61.       if (fsptr)
  62.       {
  63.             if (fseek(fsptr, 0L, SEEK_END) != 0)
  64.                   return ERROR;  /* seek failure */
  65.             rec.delete_flag = 0; /* active record tag */
  66.             rec.recordnum = (int) (ftell(fsptr) / 
  67.                   (long) sizeof(struct blackbook));
  68.             if (fwrite(&rec, sizeof(struct blackbook), 1, fsptr) != 1)
  69.             {
  70.                   return ERROR; /* write error */
  71.             }
  72.             else
  73.             {
  74.                   /* put your clean up code here */ 
  75.                   return OK;
  76.             }
  77.       }
  78.       return ERROR;
  79. }
  80.  
  81. /* tag the last record read in the file as deleted */
  82.  
  83. int data_delete(void)
  84. {
  85.       if (fsptr)
  86.       {
  87.             if (fseek(fsptr, (long) sizeof(struct blackbook) * -1L,
  88.                   SEEK_CUR) != 0)
  89.             {
  90.                   return ERROR;
  91.             }
  92.             rec.delete_flag = -1;   /* tag the record as deleted */
  93.             if (fwrite(&rec, sizeof(struct blackbook), 1, fsptr) != 1)
  94.                   return ERROR;
  95.             else  return OK;
  96.       }
  97.       return ERROR;
  98. }
  99.  
  100. /* read a random structure. If successful the global cur_rec will 
  101.  * contain the number of the last record read & it can be compared
  102.  * to the number in the struct as a double check (belt & suspenders)
  103.  */
  104.  
  105. int data_read(long recnum)
  106. {
  107.       if (fseek(fsptr, (long) sizeof(struct blackbook) * recnum,
  108.             SEEK_SET) != 0)
  109.       {
  110.             return ERROR;
  111.       }
  112.       cur_rec = recnum; /* keep tabs on record pointer in global */  
  113.  
  114.       /* now read the record into save struct*/
  115.  
  116.       if (fread(&oldrec, sizeof(struct blackbook), 1, fsptr) != 1)
  117.       {
  118.             return ERROR;
  119.       }
  120.       else                          /* copy save struct to edit struct */
  121.       {
  122.             memcpy(&rec, &oldrec, sizeof(struct blackbook));
  123.             return OK;
  124.       }
  125. }
  126.  
  127. /* rewrite the last read record back to disk */
  128.  
  129. int data_update(void)
  130. {
  131.       if (memcmp(&rec, &oldrec, sizeof(struct blackbook)) == 0)
  132.             return TRUE;  /* no update needed */
  133.  
  134.       /* back up one record before writing */
  135.  
  136.       if (fseek(fsptr, (long) sizeof(struct blackbook) * -1L, 
  137.             SEEK_CUR) != 0)
  138.       {
  139.             return ERROR; /* seek error */ 
  140.       }
  141.  
  142.       /* now write the record */
  143.  
  144.       if (fwrite(&rec, sizeof(struct blackbook), 1, fsptr) != 1)
  145.             return ERROR; /* write error */
  146.       return OK;
  147. }
  148.  
  149. /* get the next valid record in the file */
  150.  
  151. int read_forward(void)
  152. {
  153.       do
  154.       {
  155.             cur_rec++; /* upcount the record number */
  156.             if (data_read(cur_rec) != 0)
  157.             {
  158.                   cur_rec--; /* decrement the record number */
  159.                   return ERROR;
  160.             }
  161.       } while (oldrec.delete_flag != 0); /* record read was deleted */
  162.       return OK;
  163. }
  164.  
  165. /* get the previous valid record in the file */
  166.  
  167. int read_backward(void)
  168. {
  169.       do
  170.       {
  171.             cur_rec--;  /* decrement the record number */
  172.             if (cur_rec >= 0)
  173.             {
  174.                   if ( data_read(cur_rec) != 0 )
  175.                   {
  176.                         cur_rec++; /* increment the record number */
  177.                         return ERROR;
  178.                   }
  179.             }  
  180.       } while (oldrec.delete_flag != 0); /* record read was deleted */
  181.       return OK;
  182. }
  183.